package com.yixq.soa.service.web.utils;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.yixq.soa.service.web.service.DataValidService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.yixq.soa.service.web.auth.UserRealm;
import com.yixq.soa.service.web.dto.DoorduResult;
import com.yixq.soa.service.web.dto.ObjectResult;
import com.github.miemiedev.mybatis.paginator.domain.PageList;

public class BaseController {

	@Value("${door.test.unitId}")
	public Integer defaultTestUnitId;

	public ResponseEntity<Object> ResponseJSON(Object body) {
		return ResponseJSON(body,HttpStatus.OK);
	}
	
	public ResponseEntity<Object> ResponseJSON(Object body,HttpStatus status) {
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON);
		ResponseEntity<Object> res = new ResponseEntity<Object>(body, headers, status);
		
		//_$_beginTime
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		
		Long beginTime = (Long)request.getAttribute("_$_beginTime");
		if(beginTime != null && beginTime > 0){
			HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
					.getResponse();
			
			Long maxTime = (Long)request.getAttribute("_$_use_time_max");
			
			Long endTime = System.currentTimeMillis();
			Long userTime = endTime - beginTime;
			response.addHeader("time-used", userTime+"ms");
			
			if(maxTime < userTime){
				//log warn
			}
			
		}
		

		return res;
	}

	/**
	 * 
	 * @Title: result
	 * @Description 正确返回调用此方法
	 * @param t
	 *            DoorduResult 的子类
	 * @return 如果DoorduResult的参数没有指定,则自动赋值为操作成功的值.
	 */
	private <T extends DoorduResult<?>> ResponseEntity<Object> result(T t) {
		DoorduResult<?> r = (DoorduResult<?>) t;

		if (r.getSuccess() == null) {//没有指定则设置为 true
			r.setSuccess(true);
		}

//		if (r.getTotalCount() == null) {//没有设置记录数则自动设置
//			Object o = r.getData();
//			Long dc = 0L;
//			if (o != null) {//data 不为空则设置为 1
//				dc = 1L;
//				if (o instanceof PageList) { //如果为分页数据则设置为实际的总数
//					PageList<?> pl = (PageList<?>) o;
//					if (pl.getPaginator() != null) {
//						dc = Long.valueOf(pl.getPaginator().getTotalCount());
//					}
//				}
//			}
//
//			r.setTotalCount(dc);
//		}
		
		
		return ResponseJSON(t);
	}
	

	/**
	 * 返回错误结果.
	* @Title: error 
	* @Description
	* @param t
	* @return
	 */
	public <T extends DoorduResult<?>> ResponseEntity<Object> error(T t){
		if(t != null){
			DoorduResult<?> r = (DoorduResult<?>) t;
			if(r.getSuccess() == null){
				r.setSuccess(false);
			}
		}

		return ResponseJSON(t);
	}

	/**
	 * 返回正确的响应(200状态码)<br>
	 * <p>如果传递的参数为分页对象 {@code PageList}, 则使用分页数据中的总记录数</p>
	 * <p>如果传递的参数为结果对象 {@code DoorduResult}, 则完全使用该对象的属性进行输出.</p>
	 * <p>其他对象则使用默认封装后输出.</p>
	 * @param result 可以为 null,PageList,DoorduResult 3种对象.其他对象将使用默认输出.
	 * @return 封装好的返回对象 {@code ResponseEntity}
	 */
	public ResponseEntity<Object> ok(Object result) {
//		int totalCount = 0;
//		if (pagelist == null) {
//			return ok(null, 0);
//		}
//
//		if (pagelist.getPaginator() != null) {
//			totalCount = pagelist.getPaginator().getTotalCount();
//		}
//
//		return ok(pagelist, totalCount);
		
		if(result == null){
			return ok(new Object(),"");
		}
		
		if(result instanceof PageList){
			PageList<?> pagelist = (PageList<?>)result;
			
			Long dc = 0L;
		
			
			if (pagelist.getPaginator()!= null) {//没有设置记录数则自动设置
				dc = Long.valueOf(pagelist.getPaginator().getTotalCount());
			}
			
			return ok(pagelist,dc);
		}
		
		if(result instanceof DoorduResult){
			DoorduResult<?> dresult = (DoorduResult<?>)result;
			return result(dresult);
		}
		
		
		return ok(result,"");
		
	}


	
	/**
	 * 正常接口返回,推荐使用 {@code ok(DoorduResult<?> result) }  方法
	 * @see
	 * @param data
	 * @param message
	 * @return
	 */
	public ResponseEntity<Object> ok(Object data, String message) {
		return ok(data,0L, message, true, DoorduResult.DEFAULT_SUCCESS_CODE);
	}
	
	/**
	 * 正常接口返回,推荐使用 {@code ok(DoorduResult<?> result) }  方法
	 * @see
	 * @param data
	 * @param totalCount
	 * @return
	 */
	public ResponseEntity<Object> ok(Object data,Long totalCount) {
		return ok(data, totalCount, "", true, DoorduResult.DEFAULT_SUCCESS_CODE);
	}

	/**
	 * 正常接口返回,推荐使用 {@code ok(DoorduResult<?> result) }  方法
	 * @param data
	 * @param totalCount
	 * @param msg
	 * @param success
	 * @param code
	 * @return
	 */
	public ResponseEntity<Object> ok(Object data,Long totalCount, String msg, Boolean success, String code) {
		ObjectResult result = new ObjectResult();
		result.setData(data==null ? new Object():data);
		result.setMessage(msg);
		result.setSuccess(success);
		result.setTotalCount(totalCount);
		result.setCode(code);
		
		//TODO Map对象的属性不能自动转换null 为 ""
		
		return ResponseJSON(result);
	}

	/***
	 * 返回业务异常
	 * 
	 * @param msg
	 * @return
	 */
	public ResponseEntity<Object> error(String msg) {
		return error(msg, false, null);
	}
	

	/***
	 * 
	 * @param msg
	 * @param code
	 * @return
	 */
	public ResponseEntity<Object> error(String msg, String code) {
		return error(msg, false, code);
	}

	/**
	 * 
	 * @param msg
	 * @param succcess
	 * @param code
	 * @return
	 */
	public ResponseEntity<Object> error(String msg, Boolean succcess, String code) {
		Map<String, Object> data = new HashMap<>();
		data.put("message", msg);

		data.put("success", succcess);

		if (code != null) {
			data.put("code", Integer.valueOf(code));
		}else{
			data.put("code", "400");
		}

		//data.put("data", new Object());
		
		return ResponseJSON(data,HttpStatus.BAD_REQUEST);
	}
	
	/***
	 * 获取当前的请求信息.
	 * @return
	 */
	public HttpServletRequest getRequest() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		
		return request;
	}
	
	
	
	/**
	 * 获取当前登录的用户信息
	 * @return
	 */
	public Optional<UserRealm>  getUserRealm(){
		HttpServletRequest request = getRequest();
		HttpSession session = request.getSession(false);
		if(session != null){
			UserRealm realm = (UserRealm)session.getAttribute(UserRealm.USER_REALM_KEY);
			return Optional.ofNullable(realm);
		}
		return Optional.empty();
	}

	/**
	 * 校验数据的合法性
	 * @param object
	 * @return
	 */
	public String checkData(Object object){
		String result = null;
		try {
			DataValidService.valid(object);
		} catch (Exception e) {
			//e.printStackTrace();
			result = "参数校验失败："+e.getMessage();
		}
		return result;
	}

}
